export default class PictureEditWebSocket {
  private socket: WebSocket | null
  private readonly eventHandlers: any
  private readonly connectUrl: string

  constructor(connectUrl: string) {
    this.socket = null
    this.eventHandlers = {}
    this.connectUrl = connectUrl
  }

  public connect() {
    this.socket = new WebSocket(this.connectUrl)
    console.log(this.socket)

    // 携带cookie
    this.socket.binaryType = 'blob'

    // 监听连接成功事件
    this.socket.onopen = () => {
      console.log('WebSocket连接建立')
      this.triggerEvent('open')
    }

    // 监听消息事件
    this.socket.onmessage = (event) => {
      const message = JSON.parse(event.data)
      console.log('收到消息', message)

      // 根据消息触发对应的事件
      this.triggerEvent(message.type, message)
    }

    // 监听连接关闭事件
    this.socket.onclose = (event) => {
      console.log('WebSocket连接关闭', event)
      this.triggerEvent('close', event)
    }
    // 监听错误事件
    this.socket.onerror = (error) => {
      console.log('WebSocket连接错误', error)
      this.triggerEvent('error', error)
    }
  }

  /**
   *  关闭webSocket连接
   */
  public disconnect(){
    if (this.socket) {
      this.socket.close()
      this.socket = null
      console.log('WebSocket 连接已经手动关闭')
    }
  }

  /**
   *  发送消息
   * @param message 消息对象
   */
  public sendMessage(message: object){
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(message))
      console.log('消息已发送', message)
    } else {
      console.log('WebSocket 未连接，无法发送消息', message)
    }
  }

  /**
   * 添加自定义事件
   * @param type 消息类型
   * @param handler 事件处理函数
   */
  public on(type: string, handler: (data?: any) => void) {
    // 添加事件
    if (!this.eventHandlers[type]) {
      this.eventHandlers[type] = []
    }
    this.eventHandlers[type].push(handler)
  }

  /**
   * 触发事件
   * @param type 消息类型
   * @param data 消息数据
   */
  public triggerEvent(type: string, data?: any): void {
    // 添加事件
    const handlers = this.eventHandlers[type]
    if (handlers) {
      handlers.forEach((handler: any) => {
        handler(data)
      })
    }
  }
}
